iT邦幫忙

2024 iThome 鐵人賽

DAY 16
0
Software Development

輕鬆學習設計模式Design Pattern系列 第 16

Day 16 中介者模式 Mediator Pattern

  • 分享至 

  • xImage
  •  

有時候我們在開發大型系統時,會發現各個物件之間的溝通漸漸變得複雜無比,像是織了一張錯綜複雜的蜘蛛網。每個物件彼此依賴,要新增或修改功能時牽一髮而動全身。這時候中介者模式 Mediator Pattern 就像是一個「協調者」,能讓物件之間的溝通變得有條不紊,不用每個物件都互相認識。今天我們來聊聊這個神奇的模式!

什麼是中介者模式?

中介者模式是一種行為型設計模式,用來定義一個物件,負責協調其他多個物件之間的互動。這個模式的核心概念是:物件之間不直接溝通,而是透過一個「中介者」來傳遞訊息或協調行為。這樣做的好處是,我們可以減少物件之間的耦合度,使系統更易於維護與擴展。

打個比方,想像你在公司裡面工作,當你需要和不同部門溝通時,不需要直接找每個部門的人,而是透過人力資源部門(HR)。HR 就是這裡的「中介者」,它負責協調你與各部門之間的溝通,讓事情變得更簡單明瞭。

中介者模式在聊天室應用中的實例

最經典的中介者模式應用場景之一就是「聊天室」。在一個聊天室中,每個使用者都可以發訊息給其他使用者。如果沒有中介者模式,所有使用者都需要相互認識才能互相溝通,這會讓系統變得非常混亂且難以擴展。而有了中介者後,每個使用者只需要和中介者溝通,中介者再把訊息傳遞給其他相關的使用者。

首先我們先定義中介者介面,中介者需要有一個統一的介面,定義訊息如何在物件間傳遞,

class ChatUser; // 前向宣告

// 中介者介面
class ChatRoom {
public:
    virtual void sendMessage(const ChatUser* sender, const std::string& message) = 0;
    virtual ~ChatRoom() = default;
};

這個具體的中介者負責管理聊天室中的使用者,並將訊息傳遞給正確的接收者,

// 具體中介者
class ConcreteChatRoom : public ChatRoom {
private:
    std::vector<ChatUser*> chatUsers;

public:
    void addUser(ChatUser* user) {
        chatUsers.push_back(user);
    }

    void sendMessage(const ChatUser* sender, const std::string& message) override {
        for (ChatUser* user : chatUsers) {
            if (user != sender) {
                user->receive(sender->getName() + ": " + message);
            }
        }
    }
};

聊天室的使用者實作一個可以和中介者溝通的介面,

// 參與者
class ChatUser {
private:
    std::string name;
    ChatRoom* chatRoom;

public:
    ChatUser(const std::string& name, ChatRoom* room) : name(name), chatRoom(room) {}

    void send(const std::string& message) const {
        std::cout << name << " 發送消息: " << message << std::endl;
        chatRoom->sendMessage(this, message);
    }

    void receive(const std::string& message) {
        std::cout << name << " 收到消息: " << message << std::endl;
    }

    std::string getName() const {
        return name;
    }
};

在客戶端,使用者透過中介者來發送和接收訊息,而不需要知道其他使用者的存在,

// 客戶端使用
int main() {
    ConcreteChatRoom room;
    
    ChatUser john("John", &room);
    ChatUser alice("Alice", &room);

    room.addUser(&john);
    room.addUser(&alice);

    john.send("Hello, Alice!");
    alice.send("Hi, John!");

    return 0;
}

執行上述程式碼,我們會得到以下輸出:

John 發送消息: Hello, Alice!
Alice 收到消息: John: Hello, Alice!
Alice 發送消息: Hi, John!
John 收到消息: Alice: Hi, John!

中介者模式的優缺點

中介者模式最大的優勢是「解耦」,它避免了各個物件直接互相依賴,這使得系統結構更加清晰,新增或移除物件時,不需要修改其他物件的程式碼。同時,這也讓我們可以更靈活地修改中介者的行為,達到自訂溝通規則的目的。

中介者模式也有其潛在的缺點。隨著系統的擴展,中介者本身可能會變得非常複雜,尤其當有很多物件要透過中介者溝通時,這個中介者可能會變成一個大型的、難以維護的類別,反而會增加系統的負擔。

總結

中介者模式特別適合應用於多個物件需要互相溝通的情況下,比如聊天室、事件處理系統等。透過中介者可以有效地減少物件之間的耦合,讓系統更加靈活。當然和其他設計模式一樣,我們也要根據具體的需求謹慎使用,避免讓中介者本身變得過於複雜。

更多C++語言相關的文章,歡迎追蹤我的部落格。
https://shengyu7697.github.io/cpp-mediator-pattern/


上一篇
Day 15 迭代器模式 Iterator Pattern
下一篇
Day 17 備忘錄模式 Memento Pattern
系列文
輕鬆學習設計模式Design Pattern30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言